let [x, y] = [1];
console.log(`1: x = ${x}, y = ${y}`); // 1: x = 1, y = undefined
// 解构赋值左侧变量个数与右侧数组中元素的个数不一定相同。左侧多余变量会被设置为 undefined，右侧多余变量被忽略。左侧变量列表可以包含额外的逗号以跳过右侧某些值
[, x, , , y] = [1, 2, 3, 4, 5, 6, 7];
console.log(`2: x = ${x}, y = ${y}`); // 2: x = 2, y = 5
// 在解构赋值时，如果想把所有未使用或剩余的值收集到一个变量中，可以再左侧最后一个变量名前加上3个点。
[, x, , ...y] = [1, 2, 3, 4, 5, 6, 7];
console.log(`3: x = ${x}, y = ${y}`); // 3: x = 2, y = 4,5,6,7
// 解构赋值可用于嵌套数组，此时，赋值的左侧看起来也应该像一个嵌套的数组字面量。
let [a, [b, c]] = [1, [2, 2.5], 3];
console.log(`4: a = ${a}, b = ${b}, c = ${c}`); // 4: a = 1, b = 2, c = 2.5
// 数组结构的一个强大特型是，它并不要求右侧必须是数组，而可以是任何可迭代的对象。
let [first, ...rest] = "hello";
console.log(`5: first = ${first}, rest = ${rest}`); // 5: first = h, rest = e,l,l,o
// 解构赋值在右侧时对象值的情况下也可以执行，此时赋值的左侧看起来像一个对象字面量
let transparent = { red: 0.0, green: 0.0, blue: 0.0, alpah: 1.0 };
let { blue, red, g } = transparent;
console.log(`6: red = ${red}, g = ${g}, blue = ${blue}`); // 6: red = 0, g = undefined, blue = 0
// 可以把对象的全局函数复制到变量中
const { cos } = Math;
console.log(`cos(3.141) = ${cos(3.141)}`); // cos(3.141) = -0.9999998243808664
// 可以再解构时重新命名变量
const { tan: tangent } = Math;
console.log(`tangent(3.141) = ${tangent(3.141)}`); // tangent(3.141) = -0.000592653659180776
// 解构赋值可能会很复杂
let points = [
  { x: 1, y: 2 },
  { x: 3, y: 4 },
];
let [{ x: x1, y: y1 }, { x: x2, y: y2 }] = points;
console.log(`x1 = ${x1}, y1 = ${y1}, x2 = ${x2}, y2 = ${y2}`); // x1 = 1, y1 = 2, x2 = 3, y2 = 4
// 还可以解构数组的对象，不过这种结构太复杂了，不建议使用
const points2 = { p1: [10, 20], p2: [30, 40] };
const {
  p1: [x10, y10],
  p2: [x20, y20],
} = points2;
console.log(`x10 = ${x10}, y10 = ${y10}, x20 = ${x20}, y20 = ${y20}`); // x10 = 10, y10 = 20, x20 = 30, y20 = 40
